home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
151-175
/
scopedisk168
/
tinytools
/
pform
/
pform.asm
< prev
next >
Wrap
Assembly Source File
|
1995-03-19
|
5KB
|
233 lines
; Format input lines to standard output
INCLUDE "/include/init.i"
; OPT D+
; Local Equs
FormatBufSize EQU 1500
MaxLineSize EQU 512
MaxFormatArgs EQU 20
; Variable storage
STRUCT ArgArray,(1+1)*4
STRUCT ArgStream,MaxFormatArgs*4
STRUCT FormatClipInfo,2*4
LONG StdIn
LONG StdOut
LONG FormatBufPtr
SIZE
; Regs
ByteFetch EQUR D4
ReadBytesLeft EQUR D5
LineBufPtr EQUR D6
LineBufLeft EQUR D7
LineEndPtr EQUR A2
ErrorStrPtr EQUR A4
; Startup
STACK 4000
INIT
; Let ARP interpret the commandline
MOVE.L ComLineBase(GP),A0
MOVE.L ComLineSize(GP),D0
LEA HelpMsg(PC),A1
LEA ArgArray(GP),A2
LEA Template(PC),A3
MOVE.L A1,(A2)
CALL GADS
MOVE.L (A2),ErrorStrPtr
TST.L D0
BEQ ErrorExit
BMI ErrorExit
; Open the standard input & output
CALL Input
MOVE.L D0,StdIn(GP)
CALL Output
MOVE.L D0,StdOut(GP)
; Alloc tracked mem for the string format buffer.
LEA OutOfMem(PC),ErrorStrPtr
MOVE.L #FormatBufSize,D0
MOVEQ #0,D1
CALL ArpAllocMem
MOVE.L D0,FormatBufPtr(GP)
BEQ ErrorExit
; Allocate the read-line buffer
MOVE.L #MaxLineSize+4+MaxLineSize,D0 ; 2 part buf with 0 term space.
MOVEQ #0,D1
CALL ArpAllocMem
MOVE.L D0,LineBufPtr
BEQ ErrorExit
; Initialize the argument stream
MOVEQ #MaxFormatArgs-1,D0
LEA ArgStream(GP),A0
InitArgStreamLongs:
MOVE.L LineBufPtr,(A0)+
DBRA D0,InitArgStreamLongs
; ** This is an intelligent ReadLine routine.
MOVEQ #0,ReadBytesLeft
; Reinitialize the line buffer. (First part of dual buffer space)
DoForEachLine:
LEA ReadError(PC),ErrorStrPtr
MOVE.L LineBufPtr,LineEndPtr
MOVE.L #MaxLineSize,LineBufLeft
; Extract lines from the readbuffer into the line buffer.
BRA.S ExtractEntry
CopyLineBytes:
MOVE.L ByteFetch,A0
ADDQ.L #1,ByteFetch
SUBQ.L #1,ReadBytesLeft
MOVE.B (A0),D0
CMP.B #10,D0
BEQ.S GotLine
MOVE.B D0,(LineEndPtr)+
SUBQ.L #1,LineBufLeft
BEQ.S GotLine
ExtractEntry:
TST.L ReadBytesLeft
BNE CopyLineBytes
; Refill the read buffer.
MOVE.L StdIn(GP),D1
MOVE.L LineBufPtr,D2
MOVE.L #MaxLineSize,D3
ADD.L D3,D2
ADDQ.L #4,D2
CALL Read
TST.L D0
BMI.S ErrorExit
BNE.S NotYetDone
CMP.L LineBufPtr,LineEndPtr
BEQ.S Exit
NotYetDone:
MOVE.L D2,ByteFetch
MOVE.L D0,ReadBytesLeft
BNE CopyLineBytes
; Null terminate the line.
GotLine:
CLR.B (LineEndPtr)
; Format things, terminate with a LF, and write the format buffer
BSR.S VanillaDoFmt
MOVE.L FormatBufPtr(GP),A0
MOVE.B #10,-1(A0,D0.L)
LEA WriteError(PC),ErrorStrPtr
MOVE.L StdOut(GP),D1
MOVE.L A0,D2
MOVE.L D0,D3
BEQ.S WriteDone
CALL Write
CMP.L D0,D3
BNE.S ErrorExit
WriteDone:
; Check if user hit ^C
SUB.L A1,A1
CALL CheckAbort
MOVE.L A1,ErrorStrPtr
TST.L D0
BNE.S ErrorExit
BRA DoForEachLine
; Done, cleanup
Exit:
CLR.W ReturnCode(GP)
SUB.L ErrorStrPtr,ErrorStrPtr
ErrorExit:
; Display error string, if any, and exit
MOVE.L ErrorStrPtr,D0
BEQ.S NoErrorMsg
MOVE.L D0,A1
CALL Puts
NoErrorMsg:
RTS
; Subroutines
; This sub uses exec's RawDoFmt to do string formatting while clipping
; any surplus data to fit the buffer size. Arps format routines have
; no overflow checks, and since the user is not guaranteed to act
; sanely, clipping is essential.
; I : Assumes a valid format string and buffer
; O : The format buffer contain the formatted string.
; : D0.L = Size of formatted string.
Vanilla_Regs REG A2/A3/A6
VanillaDoFmt:
MOVEM.L Vanilla_Regs,-(SP)
MOVE.L ArgArray(GP),A0
LEA ArgStream(GP),A1
LEA DoClippedBufferFill(PC),A2
LEA FormatClipInfo(GP),A3
MOVE.L FormatBufPtr(GP),(A3)
MOVE.L (A3),4(A3)
ADD.L #FormatBufSize,4(A3)
MOVE.L $4.W,A6 ; exec
CALL RawDoFmt
MOVE.L (A3),D0
SUB.L FormatBufPtr(GP),D0
MOVEM.L (SP)+,Vanilla_Regs
RTS
; Assumes A0 is usable, not clear from autodocs whether this is true.
; (Default calling conventions and ROM code suggest it is)
DoClippedBufferFill:
MOVE.L (A3)+,A0
CMP.L (A3),A0
BNE.S NotYetAtBufEnd
SUBQ.L #1,A0
NotYetAtBufEnd:
MOVE.B D0,(A0)+
MOVE.L A0,-(A3)
RTS
; The string section
Template:
DC.B 'FormatString/a',0
HelpMsg:
DC.B 'PForm - Pipe formatted lines.',10
DC.B 'Usage: PForm "prefix %[width.limit]s postfix"',0
OutOfMem:
DC.B 'Out of memory!',0
ReadError:
DC.B 'Error while reading',0
WriteError:
DC.B 'Error while writing',0
CNOP 0,2
END